#pragma once
#include "Lock.hpp"
#include "Sem.hpp"
#include <vector>
#define Capacity 10

template <typename T>
class Circular_queue
{
public:
    Circular_queue(int cap = Capacity)
        : _cap(cap), _cstep(0), _pstep(0), _consum_sem(0), _produce_sem(cap)
    {
        _quenue.resize(cap);
    }
    void Equeue(T &in)
    {
        _produce_sem.P();
        {
            LockGuard plock(_pmutex);
            _quenue[_pstep] = in;
            _pstep++;
            _pstep %= _cap;
            _consum_sem.V();
        }
    }
    void Pop(T &out)
    {
        _consum_sem.P();
        {
            LockGuard clock(_cmutex);
            out = _quenue[_cstep];
            _cstep++;
            _cstep %= _cap;
            _produce_sem.V();
        }
    }
    ~Circular_queue()
    {
    }
private:
    std::vector<T> _quenue;
    int _cap;
    int _cstep;
    int _pstep;

    Sem _consum_sem;
    Sem _produce_sem;

    Mutex _pmutex;
    Mutex _cmutex;
};